package model;

import model.interfaces.selectable.SelectableCommand;
import model.interfaces.commandTypes.ArgumentsVisitor;
import model.interfaces.commandTypes.DirectionArgs;

/**
 * Command that tells an army to defend against attacks in a certain direction.
 * 
 * @author Christopher Dudley
 * @editor alex kagioglu
 */
class Defend implements Command, SelectableCommand, DirectionArgs, NotPartOfTheSystem
{
    private static final String name = "Defend";
    private Direction argument;
    
    /**
     * Creates a new Defend command with no direction.
     */
    public Defend() {
        argument = null;
    }
    
    private Defend( Direction dir ) {
        this.argument = dir;
    }
    
    /**
     * Accepts an ArgumentsVisitor so that the directional argument of the
     * command cand be correctly set.
     * 
     * @param visitor
     *            the ArgumentsVisitor
     */
    public void accept( ArgumentsVisitor visitor )
    {
        visitor.visitDirectionArgs( this );
    }
    
    /**
     * Executes the command.
     * 
     * @param player
     *            the player that owns the army defending.
     * @param instance
     *            the army that is being told to defend.
     */
    public void run( Player player, ModelInstance instance )
    {
        player.defend( instance, argument );
    }
    
    /**
     * Returns a copy of this command with the current argument set and clears
     * the argument of the current command.
     * 
     * @return a Command-type reference to copy of this command.
     */
    public Command getCommand()
    {
        Command result = new Defend( this.argument );
        this.argument = null;
        return result;
    }
    
    /**
     * Returns the name of the command.
     * 
     * @return the name of the commmand.
     */
    public String getName()
    {
        String result = Defend.name;
        if ( this.argument != null ) result = result + " " + this.argument.dir;
        return result;
    }
    
    /**
     * Sets the direction in which the army should defend against attacks.
     * 
     * @param dir
     *            the direction in which to defend.
     */
    public void setArgs( Direction dir )
    {
        argument = dir;
    }
    
    /**
     * It's not part of your system, man!
     */
    public void throwItOnTheGround()
    {
        new ThrowItOnTheGround().cuzMyDadIsNotA( this );
    }
}
